{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "04de849a-3534-4b7d-9321-8b7e97cf9494",
   "metadata": {},
   "outputs": [],
   "source": [
    "import glob\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.patches as mpatches\n",
    "\n",
    "sns.set(style=\"ticks\")\n",
    "np.set_printoptions(precision=3, suppress=True, threshold=5)\n",
    "pd.set_option('display.precision', 3)\n",
    "pd.set_option('display.max_rows', None)  # Show all rows\n",
    "\n",
    "# Set Seaborn theme for better aesthetics\n",
    "sns.set_theme(style=\"whitegrid\")\n",
    "\n",
    "color_palette = sns.color_palette('muted', 5)\n",
    "color_palette[2] = '#009E73'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "341326b9-d523-47fa-b1a3-9a9609601d3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_data(patterns, metric):\n",
    "    dfs = []\n",
    "    for pattern in patterns:\n",
    "        files = glob.glob(pattern)\n",
    "        files.sort()\n",
    "        for fname in files:\n",
    "            setting = fname.split('/eval_')[1].replace('.json', '').split('_')\n",
    "\n",
    "            df = pd.read_json(fname, orient='index').transpose()\n",
    "            df['seed'] = int(setting[0])\n",
    "            df['runs'] = int(setting[1])\n",
    "            df['noise'] = float(setting[2])\n",
    "\n",
    "            df['method'] = setting[3]\n",
    "            horizon = setting[4].split('-')\n",
    "            df['ph'] = int(horizon[0])\n",
    "            df['ah'] = int(horizon[1])\n",
    "\n",
    "            # Set default values\n",
    "            df['nsample'] = 1\n",
    "            df['nmode'] = 1\n",
    "            df['decay'] = np.nan\n",
    "\n",
    "            if setting[3] == 'coherence':\n",
    "                df['nsample'] = int(setting[5])\n",
    "                df['decay'] = float(setting[6])\n",
    "            elif setting[3] in ['positive']:\n",
    "                df['nsample'] = int(setting[5])\n",
    "                df['nmode'] = int(setting[6])\n",
    "            elif setting[3] in ['contrast', 'positive', 'negative']:\n",
    "                df['nsample'] = int(setting[5])\n",
    "                df['nmode'] = int(setting[6])\n",
    "            elif setting[3] == 'bid':\n",
    "                df['nsample'] = int(setting[5])\n",
    "                df['nmode'] = int(setting[6])\n",
    "                df['decay'] = float(setting[7])\n",
    "            elif setting[3] in ['cma', 'cwarm']:\n",
    "                df['nsample'] = int(setting[5])\n",
    "                df['decay'] = float(setting[6])\n",
    "            elif setting[3] == 'ema':\n",
    "                df['decay'] = float(setting[5])\n",
    "\n",
    "            dfs.append(df)\n",
    "    \n",
    "    dff = pd.concat(dfs, ignore_index=True)\n",
    "    dff['decay'] = dff['decay'].astype(float)\n",
    "    dff['nsample'] = dff['nsample'].astype(int)\n",
    "    dff['nmode'] = dff['nmode'].astype(int)\n",
    "    dff['runs'] = dff['runs'].astype(int)\n",
    "    dff[metric] = dff[metric].astype(float)\n",
    "    \n",
    "    method_order = {'random': 0, 'warmstart': 0.8, 'ema': 1, 'bid': 2}\n",
    "    dff['sort_key'] = dff['method'].apply(lambda x: method_order.get(x.lower(), len(method_order)))\n",
    "    \n",
    "    dff = dff.sort_values(['noise', 'ah', 'sort_key', 'method', 'nsample', 'decay', 'nmode', 'seed', metric]).drop('sort_key', axis=1)\n",
    "    cols = ['noise', 'ah', 'method', 'nsample', 'decay', 'nmode', 'seed', metric]\n",
    "\n",
    "    dff = dff[cols]\n",
    "\n",
    "    return dff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "89894d4a-19bb-488f-9533-681f117e789d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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KFavXh0jR45MP0CPiDjyyCMjLy8vHn30UQ/RgUTUN09t6c4774xUKhXnnHOOSRWQKHMpoKVLYi61pd/+9rcxYMCA2G+//RojXKCdcb8HrUvuQXtF5z13rXO/7B55X3xSC5TUPGrt2rXRtWvXjHs/WpaysrIoKyurc7/8/Pw6zaUhaeZSQHOpU0HCG2+8Ebvsskt069Yto33vvfdOv15bsqqsrIyIiC5dutR4rUuXLvHGG29EVVVVZGdn1yUcgBrqm6eqLV26NO6888748Y9/XGvOAmgIcymgpWvoXGpLr7/+epSWlsb555+feJxA++R+D1qX7B5dW+3WC/WRxDzq6KOPjnXr1kVeXl4cffTRMXHixOjbt2+jxUz9TJ8+PaZMmVLnfpMmTYrJkycnHxBsI3MpoLnUqSBh+fLl0a9fvxrt1W0ffvhhrf123nnnyMrKihdffDG+/vWvp9v/+c9/xsqVKyMiYtWqVdGrV6+6hJNh8+bNUVpamvGeFRUVGTH1798/srOzY/HixRmxd+vWLd5+++10W8+ePaNv377x7rvvxqb/29csLy8v8vPzY+nSpVFRUREREZ06dYqBAwfG8uXLM65p8ODBsXr16vjoo4/S7TvttFNs2rQpo3LyS1/6UnTu3Dnee++9dFvv3r2jV69e8c9//jNSqVRERHTv3j223377eP/99zM+kNhxxx3jgw8+SO/Tmp2dHbvuumusXLkyPv744/SYu+yyS6xbt67G7yIrKyuWLFnyub+L7bbbLvr06RPvvPNObN68OeN3sWTJkli/fn2N38Xq1avT/QsKCuKTTz6JFStWZPwuNm7cGB988EG6bYcddoicnJyM30WfPn1iu+22y/j3uq2/iw4dOsQuu+wSK1asiE8++eRzfxc77rhjRETG72L77bePvLy8eOeddz73d9G1a9fYYYcdMn4XOTk5sdNOO8WHH34Ya9as+dzfxcCBA6OysrLG76JTp04Z19gaVVZWxvvvv1/jd5GVlRW77bZbfPzxx7Fx48bo1KlTou9b3zxV7dprr4099tgjTjjhhETjau4cteXf5W677SZH/R85So76vBy1cuXKxPNUS51LNXeO2vK/sVQqFatWrWrWHNXa/9suLS3d5hzVGlVfoxyVfI6KaPhcakvz5s2LiIiSkpIGxyVPNf5cast5QUSYS4W51OdpbXOpau73Wm+O2rx5c6xbty792tKlS9PFuM2Zo1ojc6mWmaN69OgRZ5xxRhQVFUVOTk688MILMWPGjHj11VfjkUceqfHhYV3JU8nmqeHDh8e+++4b3bt3j+222y6WLl0a5eXlceqpp0ZExPz582PNmjWxYcOGiIjo2LFj5OfnR05OTsa/h9Y2l9oyD3/2vylzqbppjXkqwlyqteSoaq3h2XlrZC5VvxxVp4KE9evXR05OTo32zp07p1+vTe/evWPkyJExZ86cKCgoiGOPPTaWLVsWV155ZXTq1Ck2btyY/p9zfXXo0CEKCgoy2rp37x7du3evce5nz9ta284771yjrX///jXatkzgu+22W2RlZUXPnj2jZ8+eGefl5ORs83vvtttuNdp22mmnGm077LBDjbbevXvX2Gusob+LXXbZpUZb9WRkS/369avxP7Ttttsutttuu4y2uvwuamvb1t9Fnz59ok+fPhltTfW72H777WP77bfPaKvtd9GpU6etvndtf2+tRfXkMqL230WvXr0Sf4AeUf88FRHx/PPPx1NPPRUPP/xw4nE1d4767N+lHPUvctS/yFH/0qtXr0bJUy11LtXcOSov719LsraEedSn/4421nitNfjs72lrOSonJyda623RltcoR7WsudSWqqqq4tFHH40999yz1n9HdSVP/UtjzaWqH4RVM5f6F3OpmlrbXCrC/V5rz1ERkZGn+vfvH127Zn7zvilzlLlUy9Yac9T48eMzfh4+fHjsvffecemll8aMGTPivPPOa1Bs8tS/JJGnPtu+3377ZeSooqKiGjlqa1rTXGrLa6ztv6mI1jeXqlpdHlWr12W0pf7vQ+yIiE1LP4qsjjU/RsvukdegFWBaY54yl2o9OeqzWuKzc3Oplq0xclSdChK6dOlSa0VH9QPwz1ui5Yorroj169fHddddF9ddd11EfPpNmYEDB8ZTTz2V8YAHoL7qm6c2bdoUV199dZx44onpJaoAkmYuBbR0DclTW/rrX/8ay5Yti7POOivJ8IB2zv0e0JIlNY+qNnr06LjuuuviL3/5S4MLEoDaVTz/j6h45oWtvr7qZ7Nrbc89pji6HndAY4XVaMylgOZSp4KEfv36xbJly2q0V29Z8NkKiS117949pk2bFkuXLo0lS5ZE//79Y8cdd4xTTz01evfuHT169Khj6HVXUlKSsTxIUqqqqtLH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0CiSmEsB1EedtmxYvnx59OvXr0Z7dduHH3641b4XXnhhLF68OO64446YNm1aRETk5ubGrbfeGsccc0xdwqhh2bJlsWnTpi+8gVy9enWkUqkYP358g96vqa1fvz42bNiwzTfIq1evjrxOVfG/D3+ncQNLWF6njbF69eptus7Vq1dHKjs3vnHX/CaILDkV2bmxfhuvMeLT6+yT3Tk6/OKpRo4sWX2yO2/Tv8slS5ZEx451SkNfqL556pNPPonKysov7FufKtBtzVER7SNPtYccFdE+8lRbz1ERyeepljiXkqNqag95So5quZozR0XUP0+tWrUqPv7443jxxRfj+eefj29/+9uRn58fs2bNiiuvvDI6duwYp556ar1ikqcytYccFdE685T7vZpa0lyq2imnnBJvv/12RETk5eXFBRdcECeffHK9Y5KjamqNeao95KgIc6nPamk56tprr4099tgjTjjhhMRiipCnPqs15qgI93u1kafqLom5VNLkqEztIUdFtI88JUdlqlMmW79+fcYywdU6d+6cfn1rcnJyYpdddonhw4fHcccdF5s3b46HH344/vM//zN++ctfRlFRUV1CqTH2thgwYEC936M57bTTTnU6v7VeZ/QauM2nttZr3Gm7mv+z/zyt9Tpju77bdFrHjh23+e93W9U3T23YsCEias8n1X2rz6mrulxja/13Xpc81VqvsS45KqL1Xmdd8lRrvcZtzVERyeepljiXkqNqaq3XaS6VqbVeY3PmqIj656l169ZFxKdFnj/96U/j+OOPj4iIESNGxOjRo2PatGn1LkiQpzK11mtsD3Mp93s1taS5VLVrrrkm1q5dG++//37MmjUrNmzYEJs3b47s7DotIpomR9XUKq+zHeSoCHOpz2pJOer555+Pp556Kh5++OHE4qkmT2Vqrdfofq+m1nqdrTVPNRY5KlNrvUZzqZpa6zU2Vo6qU0FCly5dorKyskZ79Yd0n7eU1BVXXBEvv/xyzJ49O32TN3LkyBg1alRcffXVMXPmzLqEkmHBggX17gu0LfXNU9WTrs/rW31OXclRQLWWOJeSo4AtNXQu1alTpxg+fHi6PTs7O0aOHBlTp06NpUuXRv/+/esckzwFVGvIXKravvvumz4+4YQT0gVUl112Wb1ikqOAavXNUZs2bYqrr746TjzxxPSy6UmSp4BqScylkiZHQftQp/Lvfv36xfLly2u0V7dtv/32tfarrKyMRx55JIYNG5ZRcd6pU6c47LDD4rXXXqs1CQLUVX3z1HbbbRc5OTn16guwrcylgJauIXOpzp07x3bbbRcdOnTIeK1Pnz4R8elyhQANUd8ctTU9e/aMgw46KObNm5dIfED7Vt8cNWfOnHj77bdj7NixsXjx4vQ/ERHl5eWxePHiqKioaLzAgXYj6bkUwLaqU0HC7rvvHu+8806sXbs2o/3ll1+OiIg99tij1n6ffPJJbNq0KTZv3lzjtU2bNkVVVVVUVVXVJRSAWtU3T2VnZ0dhYWG89tprNV575ZVXYqeddopu3bolHzDQrphLAS1dQ+ZSe+yxR6xcubJGgVT1PqS9evVqhIiB9qS+OerzrF+/PtasWZNIfED7Vt8cVVZWFhs3bozTTjstjj766PQ/EZ8WKxx99NHx7LPPNm7wQLvQGHMpgG1Rp4KEESNGxObNm+Ohhx5Kt1VWVsasWbNin332ifz8/IiIWLp0aZSWlqbP6dOnT/To0SOefvrpjIdT5eXl8fvf/z522223ZlkKBmh76punIiKGDx8er776arz66qvptn/+85/x/PPPx4gRI5rmAoA2zVwKaOkaMpcaOXJkbN68OebMmZNu27BhQ8ybNy++/OUvx5e+9KUmuQag7WpIjlqxYkWN8RYvXhzPPfdcDB48uHEDB9qF+uao448/Pm6//fYa/0REHHHEEXH77bc3ylYOQPvTkLkUQEN0rMvJ++yzT4wYMSJuuummWLFiRey8884xe/bsWLJkSVx99dXp8y677LL461//GgsXLoyIiA4dOsTZZ58dN998c4wdOzZOPPHEqKqqil//+tfxwQcfxA033JDsVQHtVn3zVETEN77xjZg5c2ZMmDAhzj777OjYsWPcfffd0adPnzj77LOb43KANsZcCmjpGjKXOvXUU+PXv/51XHHFFfH2229H//794ze/+U0sXbo0pk2b1hyXA7QxDclRo0ePjoMPPjh233336NmzZ7zzzjvxyCOPxKZNm+I//uM/muNygDamvjmqoKAgCgoKah1zwIABccwxxzRJ/EDb15C51Jo1a+K+++6LiIgXX3wxIiIeeOCB6N69e/To0SPOOOOMpr0YoFWpU0FCRMT1118fN998c8ydOzdWrVoVgwYNijvuuCP233//z+13wQUXxIABA+Lee++N22+/PSorK2PQoEFx6623xvDhw+t9AQCfVd881a1bt7jvvvvixz/+cUybNi2qqqriwAMPjB/84AfRu3fvJooeaOvMpYCWrr55qkuXLnHPPffEDTfcELNmzYp169bFHnvsEdOnT4/DDjusiaIH2rr65qjTTjst/vCHP8Sf//znKC8vj969e8ehhx4aEyZMiEGDBjVR9EBbV98cBdBU6punVq1aFbfccktG2y9+8YuIiNhxxx0VJACfKyuVSqWaOwgAAAAAAAAAoG3Jbu4AAAAAAAAAAIC2R0ECAAAAAAAAAJA4BQkAAAAAAAAAQOIUJAAAAAAAAAAAiVOQAAAAAAAAAAAkTkECAAAAAAAAAJA4BQkAAAAAAAAAQOIUJAAAAAAAAAAAiVOQAAAAAAAAAAAkTkECAAAAAAAAAJA4BQkAAAAAAAAAQOIUJAAAAAAAAAAAiVOQAAAAAAAAAAAkTkECAAAAAAAAAJA4BQkAAAAAAAAAQOIUJAAAAAAAAAAAiVOQAAAAAAAAAAAkTkECrdK4ceNi1KhRzR0G0A7MmjUrBg0aFIsXL46IT/PPuHHjMs756KOP4uKLL44DDzwwBg0aFHfffXczRAoAAABAWzBx4sQ46qijvvC8o446KiZMmNAEEQFtwdSpU2PQoEGxcuXKrZ6zrfknyfek7VOQQLv01ltvxdSpU9MfMAI0xDXXXBN//vOf47zzzovrr78+DjvssPjjH/8YU6dObe7QAAAAWo0XX3wxpk6dGqtXr27uUFqMZcuWxdSpU+ONN95o7lCg3ZOjgPaooqIipk6dGv/7v//b3KHQiilIoF1666234rbbboslS5Y0dyhAK3PXXXfFXXfdldH2/PPPx9FHHx3nnHNOnHjiiVFQUBB//OMf47bbbmumKAEAAFqfv//973Hbbbf5sG8LH374Ydx2220KEqAFkKOA9uDKK6+MJ554Iv1zRUVF3HbbbfHXv/61GaOitevY3AEAQGuSk5NTo23FihXRo0ePZogGAICIiHXr1kVeXl5zhwE0kaqqqti4cWN07ty5uUNpNJs2bYqqqqrmDgMAaGc6derU3CHQBlkhgQar3v+ltLQ0Lrnkkthvv/3iwAMPjKuuuio2bNgQERGLFy+OQYMGxaxZs2r0HzRoUMay5mvXro2rr746jjrqqBg8eHAcfPDB8c1vfjP+8Y9/1Oj71ltvxbhx42KfffaJww47LO68884vjHfWrFlxySWXRETEmWeeGYMGDYpBgwZZbgbYJuPGjYtx48ZFxKf5ZNCgQZFKpeKBBx5I55OJEyfGAw88EBGRbhs0aFBzhg20IcuWLYsf/vCHMXTo0Bg8eHAcddRRMWnSpKisrIxPPvkkrrvuuhg9enTsu+++sd9++8W5554bCxYsyBjjf//3f2PQoEHx2GOPxbRp0+Lwww+PIUOGxPjx4+Pdd99tpisDWpJtuS976KGH4phjjom99947Tj755HjhhRcy5koR/5ovfXa7vOo8tOV92AsvvBAXX3xxDBs2LAYPHhxHHHFE/PjHP47169dn9J04cWLsu+++8d5778W///u/x7777huXXnppRHz6IeXdd98dJ5xwQgwZMiQOOeSQ+NGPfhSrVq1qjF8TkKCpU6fG9ddfHxERRx99dPo+qvqZ0hVXXBFz585N/33/+c9/johPV7E79dRT48ADD4y99947vva1r2V8q69a9RjPPPNMjBo1KgYPHhwnnHBC/OlPf8o4b1vy37hx42LUqFHx2muvxamnnhp77713HHXUUfGrX/2qxvuuWLEifvjDH8YhhxwSQ4YMiZKSkpg9e3bGOdXXeNddd8Xdd98dxxxzTAwZMiRmzJgRJ598ckRE/OAHP0j/Tmp7vgY0rs/LURGfFhHdfvvtccwxx6Tv02666aaorKysMdYDDzwQJ5xwQgwePDiGDh0aU6ZMafCqCy+88EKcfPLJMWTIkDj66KNjzpw5Ga831r3iAw88EEcfffTnzgeBlm3JkiVx7LHHxqhRo+Kjjz6KiRMnxlFHHRURn85RDj744IiIuO2229K5b8vP9Ko/GzzooINi7733juHDh8dPf/rTGu+zZs2amDhxYhQXF8dXvvKV+MEPfhAVFRU1zvvNb34TX/va12LvvfeOAw44IL773e9GWVlZxjnVc7H6fEZI87BCAon5zne+EzvuuGP8x3/8R7z00ktx3333xerVq9MTtW01adKkePLJJ+OMM86IgoKC+OSTT+L//b//F6WlpbHXXnulz1u1alWce+65ceyxx8bIkSPjySefjBtvvDEKCwvjiCOO2Or4+++/f4wbNy7uu+++OP/882O33XaLiIiCgoL6XTjQbu2///5x/fXXx/e///049NBD48QTT4yIiIEDB8aHH34Yzz77bJ1zIMDnWbZsWZx88smxZs2aOOWUU2K33XaLZcuWxZNPPhnr16+P999/P5555pkYMWJEDBgwID766KN46KGH4owzzohHH300vvSlL2WMd+edd0ZWVlacffbZsXbt2vjv//7vuPTSS2PmzJnNdIVAS/FF92UzZ86MH/3oR7HvvvvG+PHj4/33348LLrggevbsGfn5+fV6zyeeeCLWr18fp512Wmy33XbxyiuvxP333x8ffPBB3HrrrRnnbtq0Kc4555z4yle+Epdddll06dIlIiJ+9KMfxezZs+NrX/tajBs3LhYvXhwPPPBAvP766/GrX/3Kt32gBTv22GPjnXfeid/+9rfxgx/8IHr16hUREb17946IT7fKe/zxx+P000+PXr16xY477hgREffee28cddRRMXr06Ni4cWM8+uijcckll8T06dNj2LBhGe/x//7f/4unnnoqvvGNb0TXrl3jvvvui4svvjh+//vfp9+vLs+lzjvvvBg5cmSccMIJ8fjjj8fkyZOjU6dO6SKC9evXx7hx4+K9996L008/PQYMGBBPPPFETJw4MVavXh3jx4/PiG/WrFmxYcOGOOWUUyInJyeOPfbYKC8vj1tvvTXGjh0bX/nKVyIiYr/99kv+XwDwub4oR/3Xf/1XzJ49O4YPHx7f/OY345VXXonp06dHaWlp3H777elxpk6dGrfddlsccsghcdppp8Xbb78dv/rVr+LVV1+t91zl3XffjUsuuSROPvnk+OpXvxqPPPJITJw4Mfbaa6/4t3/7t4iIRrlXnDFjRlxxxRVRXFwcZ511VixZsiS+9a1vRY8ePWKHHXao83UATe+9996L8ePHR8+ePeMXv/hFOqdV6927d0yePDkmT54cxx57bBx77LEREekv3y1YsCBOP/306NixY4wdOzZ23HHHeO+99+J//ud/4rvf/W7GWN/5zndiwIAB8b3vfS9ef/31mDlzZvTu3Tv+8z//M33OtGnT4pZbbomRI0fGySefHCtXroz7778/Tj/99JgzZ07GKsX1/YyQZpKCBrr11ltThYWFqfPPPz+jffLkyanCwsLUG2+8kXr//fdThYWFqUceeaRG/8LCwtStt96a/vkrX/lKasqUKZ/7nmeccUaqsLAwNXv27HTbhg0bUoceemjqoosu+sKYH3/88VRhYWHq+eef/8JzgfbtkUceSRUWFqbef//9VCr1af4544wzMs4pLCyskbemTJmSKiwsbLI4gfbh+9//fmr33XdPvfLKKzVeq6qqSm3YsCG1efPmjPb3338/NXjw4NRtt92Wbnv++edThYWFqZEjR6Y2bNiQbr/nnntShYWFqYULFzbeRQCtwufdl1VWVqYOPvjg1IknnpiRQx566KFUYWFhxlzps3OpatV5aMt7soqKihrvNX369NSgQYNSS5YsSbdddtllqcLCwtSNN96Yce7f/va3VGFhYWru3LkZ7X/6059qbQdanv/+7/+uNWcUFhamdt9999SiRYtq9Pls7qisrEyNGjUqdeaZZ9YYY6+99kq9++676bY33ngjVVhYmLrvvvvSbXV5LvWLX/wi3bZhw4bUiSeemDr44INTlZWVqVQqlbr77rtThYWFqd/85jcZ8Y0dOzZVVFSUWrNmTSqVSqWfm+23336pFStWZLzXK6+8stVnakDT2lqOqs4ll19+eUb7tddemyosLEw999xzqVQqlVqxYkVqr732Sp199tkZ9233339/qrCwMPXrX/863XbZZZeljjzyyC+M6cgjj0wVFham/va3v6XbVqxYkRo8eHDq2muvTbclfa+4YcOG1AEHHJD6+te/ntq4cWP6vFmzZtWYDwItR/XneStWrEi99dZbqaFDh6a+/vWvpz755JP0OZ/NPytWrKjxOV61008/PbXvvvtm3K+lUp8+o/rse/7gBz/IOOdb3/pW6oADDkj/vHjx4tQee+yRmjZtWsZ5CxcuTO25554Z7Q39jJCmZ8sGEnP66adn/HzGGWdERNRY+u6L9OjRI15++eVYtmzZ556Xl5eX/jZyxKf7ug8ZMiTef//9Or0fAEBrUFVVFc8880wceeSRMWTIkBqvZ2VlRU5OTmRnfzrF37x5c3z88ceRl5cXu+66a7z++us1+nzta1+LnJyc9M/FxcUREeZTwOfel7322muxYsWKOPXUUzNyyFe/+tXo3r17vd+zepWDiIh169bFypUrY999941UKlVrDjvttNMyfn7iiSeie/fuceihh8bKlSvT/+y1116Rl5dnmz5o5fbff//48pe/XKN9y9yxatWqWLNmTXzlK1+pNW8ccsghMXDgwPTPu+++e3Tr1i1j7rOtz6WqvwlYLScnJ8aOHRsrVqxIb+/wpz/9Kfr16xejRo1Kn9epU6cYN25crFu3Lv72t79ljHncccfV+GYi0PL98Y9/jIiIb37zmxntZ599dsbrf/nLX2Ljxo1x5plnpu/bIiLGjBkT3bp1S59XV1/+8pfT93IRn36jedddd83IbUnfK7722mvxySefxCmnnBIdO/5rIe7Ro0dHz54963UdQNNZtGhRjBs3Lnbccce4++676/V3u3Llyvjb3/4WX//616N///4Zr2VlZdU4/9RTT834ubi4OD755JNYu3ZtREQ8/fTTUVVVFSNHjsy4n+vbt2/svPPONe7nfEbYutiygcTsvPPOGT8PHDgwsrOza+wV+kUuvfTSmDhxYgwbNiz22muvOOKII+Kkk06KnXbaKeO8HXbYoUZS69mzZyxcuDD98/LlyzNe7969e8aNKgBAa7Fy5cpYu3ZtesnN2lRVVcW9994bM2bMiMWLF8fmzZvTr2233XY1zv/sDWP10ncN3b8UaP0+775s6dKlEVHzHrBTp0417tvqYunSpXHrrbfG//zP/8SqVasyXqt+SFWtY8eONZYCfvfdd2PNmjXpPU4/a8WKFfWODWh+AwYMqLX997//fUybNi3eeOONjL3aa3sQXtuWMj179syY+2zrc6ntt98+8vLyMtp22WWXiPh0L+aioqJYsmRJ7LzzzhkfPEb8a9vQ6nz6RdcItGxLliyJ7OzsjIKniIh+/fpFjx49YsmSJRHxr7/56i2Eq+Xk5MROO+2UPq+utpbbtpxPJX2vWH0tn73mjh07prfUAVqu888/P/r27Rt33XVXdO3atV5jVH/wX1hYuE3nby2vrFq1Krp16xbvvPNOpFKpOO6442rtv2XxU8S2fUZIy6EggUazZSKo7SYwIjImPtWOP/74KC4ujqeffjqeffbZuOuuu+LOO++MqVOnZuz70qFDhy+MYejQoRk/X3PNNfG1r31tWy8BAKBVueOOO+KWW26Jr3/963HJJZdEz549Izs7O3784x9HKpWqcf5nH45Xq+1coH35vPuyutjavWBVVVXGz5s3b45vfvOb6X1Ad9ttt8jLy4tly5bFxIkTa5y/5bf8thyzT58+ceONN9b6nr51DK1bbV8weeGFF+KCCy6I/fffPyZNmhT9+vWLTp06xSOPPBK//e1va5y/tWdJW859tvW5VGPwJRpo3bY272ls2/Kc3L0isKXhw4fH7NmzY968eTVWLmgsX5RXqqqqIisrK+68885a89pnC0G3JffRcihIIDHvvvtuRrX4u+++G1VVVTFgwID0ci+f/bbdZyvBq22//fZx+umnx+mnnx4rVqyIr371q3HHHXfU+cbvl7/8ZcbP1Uv7NdfkEGg/5Bkgab17945u3brFokWLtnrOk08+GQceeGD8+Mc/zmhfvXp19OrVq7FDBNqYrd2Xff/734+IT+/5tlyNYOPGjbF48eLYfffd023V33pZs2ZNxtif/Qbgm2++Ge+8805cd911cdJJJ6Xbn3322W2Od+DAgfHcc8/Ffvvt50M9aKXqeh/15JNPRufOneOuu+7KWFr8kUceaVAc2/Jc6sMPP4x169ZlPBx/5513IiLS3w7ecccdY+HChVFVVZXxEP6f//xnRNT8pmBt3FtCy7G1v8cdd9wxqqqq4t13302vgBIR8dFHH8Xq1avTOaH6b/6f//xnxnP0ysrKWLx4cRxyyCGNFnvS94rV1/Lee+/FQQcdlG7ftGlTLFmyJAYNGtSwgIFG9f3vfz86dOgQU6ZMia5du8bo0aO3eu7Wcl91HnvzzTcTiWngwIGRSqViwIABseuuuyYyJi1H7eUoUA8PPPBAxs/3339/REQcfvjh0a1bt+jVq1e88MILGefMmDEj4+fNmzfXeFDVp0+f2H777TOW3dtWhxxySMY/22+/fURE5ObmRkTNh2IASanOM5Y9B5KSnZ0dxxxzTPz+97+PV199tcbrqVQqOnToUOMbK48//vgX7oEMsKUvui8bPHhw9O7dOx588MGM+7TZs2fXmPtUL+O75T7pmzdvjocffjjjvOoP6rbMYalUKu69995tjnvkyJGxefPm+NnPflbjtU2bNpmXQStQ1+c1HTp0iKysrIwVOBcvXhy/+93v6vX+dXkutWnTpnjooYfSP1dWVsZDDz0UvXv3jr322isiPn0mtnz58njssccy+t13332Rl5cX+++//xfG5N4SWo6t5ajqYqV77rkno736y3LVrx9yyCHRqVOnuO+++zLmPL/+9a9jzZo1jboKS9L3ioMHD47tttsuHn744di0aVO6fd68eTW23gJapiuvvDKGDx8eEydO/Ny509bmIr179479998/HnnkkRpfPq7PairHHXdcdOjQIW677bYa/VOpVHz88cd1HpOWwwoJJGbx4sVx/vnnx2GHHRYvvfRSzJ07N0aNGpX+dsyYMWPi5z//eVx++eUxePDgeOGFF+Ltt9/OGKO8vDyOOOKIGD58eOy+++6Rl5cXf/nLX+LVV1+NiRMnJhbrHnvsER06dIg777wz1qxZEzk5OXHQQQdFnz59EnsPoH2rfgB11VVXxdChQ6NDhw5xwgknNHNUQGv3ve99L5599tkYN25cnHLKKVFQUBDLly+PJ554ImbMmBHDhg2L22+/PX7wgx/EvvvuG2+++WbMmzevQXu6A+3PF92XderUKb7zne/Ej370oxg/fnwcf/zxsXjx4pg1a1aNfPNv//ZvUVRUFDfddFOsWrUqevbsGY899ljGg+uIT/dSHjhwYFx33XWxbNmy6NatWzz55JN1+gDugAMOiLFjx8b06dPjjTfeiEMPPTQ6deoU77zzTjzxxBNx+eWXx4gRIxL5HQGNo/o+6qc//Wkcf/zx0alTpzjyyCO3ev4RRxwRv/zlL+Pcc8+NUaNGxYoVK2LGjBkxcODAeu0fXJfnUttvv33ceeedsWTJkthll13iscceizfeeCOuvPLK6NSpU0REjB07Nh566KGYOHFi/OMf/4gdd9wxnnzyyXjxxRfjhz/8YXTr1u0LYxo4cGD06NEjHnzwwejatWvk5eXF3nvvbX4HzWBrOWr33XePr371q/HQQw/F6tWrY//9949XX301Zs+eHcccc0x6BYHevXvHhAkT4rbbbotzzz03jjrqqHj77bdjxowZMWTIkCgpKWm02JO+V8zJyYmLLroorrzyyhg/fnyMHDkylixZErNmzUoXpAItW3Z2dtxwww3xrW99K77zne/Ez3/+84wV8Kp16dIlvvzlL8fjjz8eu+yyS2y33Xbxb//2b1FYWBj/9V//Faeddlp89atfjbFjx8aAAQNiyZIl8Yc//CF+85vf1CmegQMHxne+8534yU9+EkuWLIljjjkmunbtGosXL45nnnkmTjnllDjnnHOSunyamIIEEnPzzTfHLbfcEj/5yU+iY8eOccYZZ6SX8oyI+Na3vhUrV66MJ598Mh5//PE4/PDD47//+78zElyXLl3itNNOi2effTaeeuqpSKVSMXDgwJg0aVJ84xvfSCzWfv36xZQpU2L69Olx+eWXx+bNm+Pee+9VkAAk5rjjjotx48bFo48+GnPnzo1UKqUgAWiwL33pS/Hwww/HLbfcEvPmzYu1a9fGl770pTj88MOjS5cucf7550dFRUXMmzcvHnvssdhzzz1j+vTp8ZOf/KS5QwdakW25Lxs7dmxs3rw57rrrrrj++uujsLAwpk2bFrfcckuN8W688cb40Y9+FD//+c+jR48ecfLJJ8eBBx4Y3/zmN9PndOrUKe6444646qqrYvr06dG5c+c49thj4/TTT48TTzxxm2O/4oorYvDgwfHggw/GT3/60+jQoUPsuOOOUVJSEvvtt1/DfzlAo9p7773jkksuiQcffDD+/Oc/R1VV1ed+Y+/ggw+Oq6++Ou6888748Y9/HAMGDIhLL700lixZUq+ChLo8l+rZs2dce+21cdVVV8XDDz8cffv2jR/96EdxyimnZIx33333xY033hizZ8+OtWvXxq677hrXXHNNfO1rX9ummDp16hTXXntt3HTTTTF58uTYtGlTXHPNNQoSoBlsLUfl5eXFVVddFQMGDIjZs2fHM888E3379o0JEybEt7/97YwxLrrooujdu3fcf//9cc0110TPnj3jlFNOie9973vpYqbG0Bj3imeccUakUqn45S9/Gdddd13svvvuMW3atLjqqquic+fOCUYPNJZOnTrFrbfeGv/+7/8eF154Ydx99921nnfVVVfFlVdeGddcc01s3Lgxvv3tb0dhYWHsvvvu6edUv/rVr2LDhg3Rv3//GDlyZL3iOe+882KXXXaJu+++O26//faIiNhhhx3i0EMPjaOOOqq+l0kLkJWqz7oZsIWpU6fGbbfdFs8991z07t27ucMBAACgmYwbNy4iIu67775mjgSg8YwbNy4+/vjj+O1vf9vcoQC0KFVVVXHwwQfHscceG1dddVVzhwNAC5Hd3AEAAAAAAADQemzYsKHGPu9z5syJTz75JA444IBmigqAlsiWDQAAAAAAAGyzl156Ka655poYMWJEbLfddvH666/Hr3/96ygsLIwRI0Y0d3gAtCAKEgAAAAAAANhmO+64Y+ywww5x3333xapVq6Jnz55x4oknxqWXXho5OTnNHR4ALUhW6rNr6gAAAAAAAAAANFB2cwcAAAAAAAAAALQ9ChIAAAAAAAAAgMQpSAAAAAAAAAAAEqcgAQAAAAAAAABInIIEAAAAAAAAACBxChIAAAAAAAAAgMQpSAAAAAAAAAAAEqcgAQAAAAAAAABInIIEAAAAAAAAACBx/z+SoBg2whUwdgAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 2100x400 with 7 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 200x20 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 220x250 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.ticker as plticker\n",
    "from matplotlib.ticker import MaxNLocator, FormatStrFormatter, LinearLocator\n",
    "\n",
    "# Set default font size\n",
    "plt.rc('font', size=12)\n",
    "plt.rc('axes', titlesize=12)\n",
    "plt.rc('axes', labelsize=12)\n",
    "plt.rc('xtick', labelsize=12)\n",
    "plt.rc('ytick', labelsize=12)\n",
    "plt.rc('legend', fontsize=12)\n",
    "\n",
    "foldername = 'result'\n",
    "all_summary = []\n",
    "\n",
    "# Define tasks and corresponding metrics\n",
    "tasks_metrics_ylim = [\n",
    "    ('pusht', 'test/mean_score', [0.78, 0.96]),\n",
    "    ('lift', 'test/mean_score', [0.04, 0.76]),\n",
    "    ('can', 'test/mean_score', [0.84, 0.96]),\n",
    "    ('square', 'test/mean_score', [0.6, 0.8]),\n",
    "    ('transport', 'test/mean_score', [0.3, 0.5]),\n",
    "    ('tool_hang', 'test/mean_score', [0.44, 0.64]),\n",
    "    ('kitchen', 'test/p_4', [0.1, 0.7]),\n",
    "]\n",
    "\n",
    "# Create a figure with horizontal subplots\n",
    "n_tasks = len(tasks_metrics_ylim)\n",
    "fig, axs = plt.subplots(1, n_tasks, figsize=(n_tasks * 3, 4))  # Adjust figsize as needed\n",
    "\n",
    "# Loop through each task and metric\n",
    "for i, (task, metric, ylim) in enumerate(tasks_metrics_ylim):\n",
    "\n",
    "    patterns = [\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_random_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_warmstart_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_ema_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_bid_*.json',\n",
    "    ]\n",
    "    df = load_data(patterns, metric)\n",
    "\n",
    "    # Filtering\n",
    "    df = df[df['noise'] == 0.0]\n",
    "    df = df[df['nsample'].isin([1, 16])]  # only consider default hyperparamter\n",
    "    df = df[~((df['method'] == 'bid') & (df['ah'] == 8))]\n",
    "\n",
    "    # Add 'name' column based on conditions\n",
    "    df['name'] = df['method']\n",
    "    df.loc[(df['method'] == 'random') & (df['ah'] == 1), 'name'] = 'closed'\n",
    "    df.loc[(df['method'] == 'random') & (df['ah'] == 8), 'name'] = 'open'\n",
    "\n",
    "    # Explode the 'metric' column to ensure scalar values\n",
    "    df = df.explode(metric)\n",
    "    df[metric] = pd.to_numeric(df[metric], errors='coerce')\n",
    "\n",
    "    # Calculate mean and standard deviation for each 'name' group\n",
    "    summary_df = df.groupby('name')[metric].agg(mean='mean', std='std').reset_index()\n",
    "\n",
    "    # Define the preferred order of bars and reorder summary_df accordingly\n",
    "    order = ['open', 'closed', 'warmstart', 'ema', 'bid']\n",
    "    summary_df = summary_df.set_index('name').reindex(order).reset_index()\n",
    "\n",
    "    # Rename the selected rows\n",
    "    rename_map = {\n",
    "        'closed': 'Vanilla',\n",
    "        'warmstart': 'Warmstart',\n",
    "        'ema': 'EMA',\n",
    "        'bid': 'BID'\n",
    "    }\n",
    "    summary_df['name'] = summary_df['name'].replace(rename_map)\n",
    "\n",
    "    # Define the color palette for different categories\n",
    "    colors = {\n",
    "        'Vanilla': 'lightgray',\n",
    "        'Warmstart': color_palette[0],\n",
    "        'EMA': color_palette[1],\n",
    "        'BID': color_palette[2],\n",
    "    }\n",
    "\n",
    "    # Define the name to exclude\n",
    "    name_to_exclude = 'open'\n",
    "\n",
    "    # Filter the summary_df to exclude the specified name\n",
    "    summary_df = summary_df[summary_df['name'] != name_to_exclude]\n",
    "\n",
    "    # Create bar plot in the current subplot\n",
    "    ax = axs[i]\n",
    "    barplot = sns.barplot(data=summary_df, x='name', y='mean', hue='name', order=summary_df['name'], palette=colors,\n",
    "                          capsize=0.1, width=0.8, edgecolor='black', linewidth=1.2, ax=ax)\n",
    "\n",
    "    # Get x positions of the bars\n",
    "    x_positions = [p.get_x() + p.get_width() / 2 for p in barplot.patches]\n",
    "    lerr = np.maximum(summary_df['std'] * 0.5, 0.01)\n",
    "    uerr = np.maximum(summary_df['std'] * 0.5, 0.01)\n",
    "\n",
    "    # Add error bars manually\n",
    "    ax.errorbar(x=x_positions, y=summary_df['mean'], yerr=[lerr, uerr], fmt='none', c='black', capsize=5)\n",
    "\n",
    "    # Adding gridlines for better readability (remove vertical lines)\n",
    "    ax.grid(axis='y', linestyle='--', linewidth=0.7, alpha=0.7)\n",
    "    ax.grid(axis='x', visible=False)\n",
    "\n",
    "    # Customize plot\n",
    "    ymin = ylim[0]\n",
    "    ymax = ylim[1]\n",
    "    ax.set_ylim(ymin, ymax)\n",
    "\n",
    "    ax.spines['top'].set_color('k')\n",
    "    ax.spines['right'].set_color('k')\n",
    "    ax.spines['left'].set_color('k')\n",
    "    ax.spines['bottom'].set_color('k')\n",
    "\n",
    "    ax.set_xticks([])  # Remove x-ticks\n",
    "    ax.set_xticklabels([])  # Remove x-tick labels\n",
    "    ax.set_xlabel('')  # Remove x-label\n",
    "    ax.set_ylabel('')  # Remove y-label\n",
    "\n",
    "    task = task.replace(\"_\", \" \")\n",
    "    title = 'push-t' if task == 'pusht' else task\n",
    "    ax.set_title(title, y=-0.15)\n",
    "\n",
    "    yticks = np.linspace(ymin, ymax, num=3)  # Adjust `num` to control the number of ticks\n",
    "    ax.set_yticks(yticks)\n",
    "    ax.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))\n",
    "\n",
    "    summary_df['task'] = task\n",
    "    all_summary.append(summary_df)\n",
    "\n",
    "# Adjust layout and show the figure\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "\n",
    "\n",
    "# Set legend\n",
    "label = list(rename_map.values())\n",
    "color = list(colors.values())\n",
    "\n",
    "# Create handles for the legend using patches (for barplots)\n",
    "handles = [\n",
    "    mpatches.Patch(color=c, label=l)\n",
    "    for c, l in zip(color, label)\n",
    "]\n",
    "\n",
    "# Create a new figure for the legend\n",
    "fig, ax = plt.subplots(figsize=(2, 0.2))  # Adjust height for better visibility\n",
    "fig.legend(handles, label, loc='center', fontsize=12, ncol=len(label), frameon=False)  # Remove the border\n",
    "ax.axis('off')\n",
    "\n",
    "# # Optionally save the figure\n",
    "# fname = f'../figures/dp_legend.png'\n",
    "# plt.savefig(fname, format='png', dpi=300, bbox_inches='tight', pad_inches=0.0)\n",
    "\n",
    "# Display the legend\n",
    "plt.show()\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "# All summary\n",
    "all_summary_df = pd.concat(all_summary, ignore_index=True)\n",
    "\n",
    "# Calculate average mean and std for each 'name' across all tasks\n",
    "average_summary_df = all_summary_df.groupby('name').agg(mean=('mean', 'mean'), std=('std', 'mean')).reset_index()\n",
    "\n",
    "# # Define the preferred order of bars and reorder average_summary_df accordingly\n",
    "order = ['Vanilla', 'Warmstart', 'EMA', 'BID']\n",
    "average_summary_df = average_summary_df.set_index('name').reindex(order).reset_index()\n",
    "\n",
    "# Create aggregated bar plot for average across all tasks\n",
    "fig, ax = plt.subplots(figsize=(2.2, 2.5))  # Adjusted size\n",
    "avg_barplot = sns.barplot(data=average_summary_df, x='name', y='mean', hue='name', order=average_summary_df['name'], palette=colors,\n",
    "                          capsize=0.1, width=0.8, edgecolor='black', linewidth=1.2, ax=ax)\n",
    "\n",
    "# Get x positions of the bars\n",
    "x_positions = [p.get_x() + p.get_width() / 2 for p in avg_barplot.patches]\n",
    "\n",
    "# Add error bars manually\n",
    "plt.errorbar(x=x_positions, y=average_summary_df['mean'], yerr=average_summary_df['std'] * 0.5,\n",
    "             fmt='none', c='black', capsize=5)\n",
    "\n",
    "# Adding gridlines for better readability (remove vertical lines)\n",
    "ax.grid(axis='y', linestyle='--', linewidth=0.7, alpha=0.7)\n",
    "ax.grid(axis='x', visible=False)\n",
    "ax.set_facecolor('#F0F3F4') \n",
    "\n",
    "# Customize plot\n",
    "avg_barplot.set_ylabel('Success Rate', fontsize=12)\n",
    "ymin = average_summary_df['mean'].min() - average_summary_df['std'].max()\n",
    "ymax = average_summary_df['mean'].max() + average_summary_df['std'].max()\n",
    "avg_barplot.set_ylim(ymin, ymax)\n",
    "\n",
    "plt.gca().spines['top'].set_color('k')\n",
    "plt.gca().spines['right'].set_color('k')\n",
    "plt.gca().spines['left'].set_color('k')\n",
    "plt.gca().spines['bottom'].set_color('k')\n",
    "\n",
    "# Customize plot\n",
    "ax.set_xticks([])  # Remove x-ticks\n",
    "ax.set_xticklabels([])  # Remove x-tick labels\n",
    "ax.set_xlabel('')  # Remove x-label\n",
    "ax.set_ylabel('')  # Remove x-label\n",
    "ax.set_title('average', y=-0.2)\n",
    "\n",
    "yticks = np.linspace(ymin, ymax, num=3)  # Adjust `num` to control the number of ticks\n",
    "ax.set_yticks(yticks)\n",
    "ax.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))\n",
    "\n",
    "# Tight layout to avoid clipping\n",
    "plt.tight_layout()\n",
    "\n",
    "# # Optionally save the figure\n",
    "# fname = f'../figures/dp_average.png'\n",
    "# plt.savefig(fname, format='png', dpi=300, bbox_inches='tight', pad_inches=0.1)\n",
    "\n",
    "# Show the plot\n",
    "plt.show()\n",
    "\n",
    "# display(average_summary_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d11a4847-131d-4609-bbac-5936059e81ae",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 450x250 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>relative_mean</th>\n",
       "      <th>relative_std</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Warmstart</td>\n",
       "      <td>0.521</td>\n",
       "      <td>0.038</td>\n",
       "      <td>0.003</td>\n",
       "      <td>0.073</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>EMA</td>\n",
       "      <td>0.615</td>\n",
       "      <td>0.038</td>\n",
       "      <td>0.182</td>\n",
       "      <td>0.072</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>BID</td>\n",
       "      <td>0.686</td>\n",
       "      <td>0.044</td>\n",
       "      <td>0.321</td>\n",
       "      <td>0.085</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Warmstart\\n+BID</td>\n",
       "      <td>0.702</td>\n",
       "      <td>0.028</td>\n",
       "      <td>0.350</td>\n",
       "      <td>0.054</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>EMA\\n+BID</td>\n",
       "      <td>0.759</td>\n",
       "      <td>0.037</td>\n",
       "      <td>0.461</td>\n",
       "      <td>0.072</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              name   mean    std  relative_mean  relative_std\n",
       "1        Warmstart  0.521  0.038          0.003         0.073\n",
       "2              EMA  0.615  0.038          0.182         0.072\n",
       "3              BID  0.686  0.044          0.321         0.085\n",
       "4  Warmstart\\n+BID  0.702  0.028          0.350         0.054\n",
       "5        EMA\\n+BID  0.759  0.037          0.461         0.072"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Define tasks and corresponding metrics\n",
    "tasks_and_metrics = [\n",
    "    ('pusht', 'test/mean_score'),\n",
    "    ('lift', 'test/mean_score'),\n",
    "    ('can', 'test/mean_score'),\n",
    "    ('square', 'test/mean_score'),\n",
    "    ('transport', 'test/mean_score'),\n",
    "    ('tool_hang', 'test/mean_score'),\n",
    "    ('kitchen', 'test/p_4'),\n",
    "]\n",
    "\n",
    "# Define the color palette for different categories\n",
    "colors = {\n",
    "    'warmstart': color_palette[3],\n",
    "    'ema': color_palette[1],\n",
    "    'bid': color_palette[2],\n",
    "    'cwarm': color_palette[3],\n",
    "    'cma': color_palette[1],\n",
    "}\n",
    "\n",
    "all_summary = []\n",
    "# Loop through each task and metric\n",
    "for task, metric in tasks_and_metrics:\n",
    "\n",
    "    patterns = [\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_random_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_warmstart_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_ema_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_bid_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_cwarm_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_cma_*.json',\n",
    "    ]\n",
    "    df = load_data(patterns, metric)\n",
    "\n",
    "    # Filtering\n",
    "    df = df[df['noise'] == 0.0]\n",
    "    df = df[df['nsample'].isin([1, 16])]    \n",
    "    df = df[~((df['method'] == 'bid') & (df['ah'] == 8))]\n",
    "\n",
    "    # Add 'name' column based on conditions\n",
    "    df['name'] = df['method']\n",
    "    df.loc[(df['method'] == 'random') & (df['ah'] == 1), 'name'] = 'closed'\n",
    "    df.loc[(df['method'] == 'random') & (df['ah'] == 8), 'name'] = 'open'\n",
    "\n",
    "    # Explode the 'metric' column to ensure scalar values\n",
    "    df = df.explode(metric)\n",
    "    df[metric] = pd.to_numeric(df[metric], errors='coerce')\n",
    "\n",
    "    # Calculate mean and standard deviation for each 'name' group\n",
    "    summary_df = df.groupby('name')[metric].agg(mean='mean', std='std').reset_index()\n",
    "\n",
    "    # Define the preferred order of bars and reorder summary_df accordingly\n",
    "    order = ['closed', 'warmstart', 'ema', 'bid', 'cwarm', 'cma']\n",
    "    summary_df = summary_df.set_index('name').reindex(order).reset_index()\n",
    "\n",
    "    summary_df['task'] = task\n",
    "    all_summary.append(summary_df)\n",
    "\n",
    "# Combine all summaries\n",
    "all_summary_df = pd.concat(all_summary, ignore_index=True)\n",
    "\n",
    "# Extract the mean value for the 'closed' category\n",
    "closed_mean = all_summary_df[all_summary_df['name'] == 'closed']['mean'].mean()\n",
    "\n",
    "# Calculate relative gain for each task and add it to the all_summary_df\n",
    "all_summary_df['relative_gain'] = all_summary_df['mean'].apply(lambda x: (x - closed_mean) / closed_mean)\n",
    "\n",
    "# Calculate average mean, std, and relative gain for each 'name' across all tasks\n",
    "average_summary_df = all_summary_df.groupby('name').agg(\n",
    "    mean=('mean', 'mean'),\n",
    "    std=('std', 'mean'),\n",
    "    relative_gain_mean=('relative_gain', 'mean'),\n",
    "    relative_gain_std=('relative_gain', 'std')\n",
    ").reset_index()\n",
    "\n",
    "# Reorder average_summary_df accordingly\n",
    "order = ['closed', 'warmstart', 'ema', 'bid', 'cwarm', 'cma']\n",
    "average_summary_df = average_summary_df.set_index('name').reindex(order).reset_index()\n",
    "\n",
    "\n",
    "# Calculate average mean and std for each 'name' across all tasks\n",
    "average_summary_df = all_summary_df.groupby('name').agg(mean=('mean', 'mean'), std=('std', 'mean')).reset_index()\n",
    "\n",
    "# Calculate relative gain compared with 'closed' and add it to the summary dataframe\n",
    "average_summary_df['relative_mean'] = average_summary_df['mean'].apply(lambda x: x / closed_mean - 1)\n",
    "average_summary_df['relative_std'] = average_summary_df['std'].apply(lambda x: x / closed_mean)\n",
    "\n",
    "# Reorder average_summary_df accordingly\n",
    "average_summary_df = average_summary_df.set_index('name').reindex(order).reset_index()\n",
    "average_summary_df = average_summary_df[average_summary_df['name'] != 'closed']\n",
    "palette = [colors[name] for name in order if name != 'closed']\n",
    "\n",
    "# Rename the selected rows\n",
    "rename_map = {\n",
    "    'warmstart': 'Warmstart',\n",
    "    'ema': 'EMA',\n",
    "    'bid': 'BID',\n",
    "    'cwarm': 'Warmstart\\n+BID',\n",
    "    'cma': 'EMA\\n+BID',\n",
    "}\n",
    "average_summary_df['name'] = average_summary_df['name'].replace(rename_map)\n",
    "\n",
    "# Create aggregated bar plot for relative mean and std across all tasks\n",
    "fig, ax = plt.subplots(figsize=(4.5, 2.5))  # Adjust the size as needed\n",
    "avg_barplot = sns.barplot(data=average_summary_df, x='name', y='relative_mean', hue='name', order=average_summary_df['name'], palette=palette,\n",
    "                         capsize=0.1, width=0.6, edgecolor='black', linewidth=1.2)\n",
    "\n",
    "# Add hatches to bars\n",
    "hatches = [\"\", \"\", \"\", \"//\", \"//\"]\n",
    "for i, bar in enumerate(avg_barplot.patches):\n",
    "    bar.set_hatch(hatches[i])\n",
    "\n",
    "# Get x positions of the bars\n",
    "x_positions = [p.get_x() + p.get_width() / 2 for p in avg_barplot.patches]\n",
    "\n",
    "# Add error bars manually\n",
    "plt.errorbar(x=x_positions, y=average_summary_df['relative_mean'], yerr=average_summary_df['relative_std'] * 0.5,\n",
    "             fmt='none', c='black', capsize=5)\n",
    "\n",
    "# Adding gridlines for better readability (remove vertical lines)\n",
    "ax.grid(axis='y', linestyle='--', linewidth=0.7, alpha=0.7)\n",
    "ax.grid(axis='x', visible=False)\n",
    "\n",
    "# Customize plot\n",
    "avg_barplot.set_ylabel(f'Relative Perf Gain', fontsize=12)\n",
    "ymin=0.0\n",
    "ymax=0.52\n",
    "avg_barplot.set_ylim(ymin, ymax)\n",
    "yticks = np.linspace(ymin, 0.5, num=5)  # Adjust `num` to control the number of ticks\n",
    "ax.set_yticks(yticks)\n",
    "ax.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))\n",
    "\n",
    "\n",
    "plt.gca().spines['top'].set_color('k')\n",
    "plt.gca().spines['right'].set_color('k')\n",
    "plt.gca().spines['left'].set_color('k')\n",
    "plt.gca().spines['bottom'].set_color('k')\n",
    "\n",
    "ax.set_xlabel('')\n",
    "ax.set_ylabel('Relative Perf Gain', fontsize=12)\n",
    "\n",
    "# Tight layout to avoid clipping\n",
    "plt.tight_layout()\n",
    "\n",
    "# # Optionally save the figure\n",
    "line_figname = '../figures/complement.png'\n",
    "plt.savefig(line_figname, format='png', dpi=300, bbox_inches='tight', pad_inches=0.1)\n",
    "\n",
    "# Show the plot\n",
    "plt.show()\n",
    "display(average_summary_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "aac40941-f862-4f16-8bb8-8dd5717a82b7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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4sSJkEgk2LNnDzw9PTFlyhQADben77//Pl577TU8/fTTmDhxIhwdHVFYWIgLFy7AysoKX375pU7XnjlzJr7//nu2e46trS2OHz+OnJwcdqljbf3+++/47LPPEBERgaCgIFhYWCAnJwdHjhyBXC7HvHnzADT8kQoJCcGOHTtQV1cHR0dH/P7778jJydHpZ9HEo+q6KQMGDMBzzz2HrVu34tatWwgLC4OJiQkyMjJw+vRpLF26FFFRUTh27BgOHjyIyMhIeHh4oKqqCvHx8bCysmoxMRsKSpxdgKenJ8aNG4djx46pbZszZw6kUinOnDmDU6dOYdiwYdixY0ezLwda6/XXX8c///yDbdu2oaqqCoMHD8by5cthbm7O7jNw4EAcPnwYn3/+Ob766itUV1fD3t4egYGBeO6553S+tkgkwqFDh7B27Vp89dVXqK2tha+vL7788ks8+eSTOp1z1KhRqKqqwu+//47z58+jrKwMNjY2CAwMxIwZMzBo0CB23/Xr12PVqlU4cOAAGIZBWFgYtm/f3m5rg2tS10157733EBAQgEOHDuGTTz6BkZERXF1dMW7cOLaj/4ABA3D9+nUkJCSguLgY1tbWCAwMxLp169jHLYaMlgcmxMA0rlG+ceNGREVF6Tscg0TPOAkhREuUOAkhREuUOAkhREv0jJMQQrRELU5CCNESJU5CCNESJU5CCNESJU5CCNESJU5CCNESJU5CCNESJU5CCNESJU5CCNESJU5CCNHS/wM/JkXEMTy3oQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 350x250 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "all_summary = []\n",
    "# Loop through each task and metric\n",
    "for task, metric in tasks_and_metrics:\n",
    "\n",
    "    patterns = [\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_random_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_bid_*.json',\n",
    "    ]\n",
    "    df = load_data(patterns, metric)\n",
    "    \n",
    "    # Filtering\n",
    "    df = df[df['noise'] == 0.0]\n",
    "    df = df[df['ah'] == 1]\n",
    "    df = df[df['method'].isin(['bid', 'random'])]\n",
    "    \n",
    "    # summary\n",
    "    summary_df = df.groupby('nsample').agg(mean=(metric, 'mean'), std=(metric, 'std')).reset_index()\n",
    "    summary_df['task'] = task\n",
    "    all_summary.append(summary_df)\n",
    "\n",
    "# All summary\n",
    "all_summary_df = pd.concat(all_summary, ignore_index=True)\n",
    "\n",
    "# Calculate average mean and std for each 'nsample' across all tasks\n",
    "average_summary_df = all_summary_df.groupby('nsample').agg(mean=('mean', 'mean'), std=('std', 'mean')).reset_index()\n",
    "\n",
    "# Define the preferred order of bars and reorder average_summary_df accordingly\n",
    "order = all_summary_df['nsample'].unique()  # Assuming you want to use all unique 'nsample' values in order\n",
    "order.sort()  # Sort the order if needed\n",
    "average_summary_df = average_summary_df.set_index('nsample').reindex(order).reset_index()\n",
    "\n",
    "# Compute the reference mean value for nsample=1\n",
    "reference_mean = average_summary_df.loc[average_summary_df['nsample'] == 1, 'mean'].values[0]\n",
    "\n",
    "# Compute the relative gain compared to nsample=1\n",
    "average_summary_df['relative_gain'] = (average_summary_df['mean'] - reference_mean) / reference_mean\n",
    "average_summary_df['relative_std'] = average_summary_df['std'] / reference_mean\n",
    "\n",
    "# Sort the dataframe by the extracted number (if needed)\n",
    "average_summary_df = average_summary_df.sort_values(by='nsample')\n",
    "\n",
    "# Create the line plot for relative gain\n",
    "fig, ax = plt.subplots(figsize=(3.5, 2.5))  # Adjust the size as needed\n",
    "\n",
    "# Adding error bars using plt.errorbar for the relative gain\n",
    "ax.errorbar(average_summary_df['nsample'], average_summary_df['relative_gain'], \n",
    "            yerr=average_summary_df['relative_std'] * 0.5, fmt='o', \n",
    "            capsize=5,\n",
    "           color=color_palette[2]) \n",
    "\n",
    "line_plot = sns.lineplot(\n",
    "    x='nsample', \n",
    "    y='relative_gain', \n",
    "    data=average_summary_df,\n",
    "    marker='o',\n",
    "    color=color_palette[2],\n",
    "    markersize=7,\n",
    "    markeredgecolor=\"k\",\n",
    "    markeredgewidth=2,\n",
    "    ax=ax,\n",
    ")\n",
    "\n",
    "# Adding labels and title with improved font size\n",
    "ax.set_xlabel('Number of Samples', fontsize=12)\n",
    "ax.set_ylabel('Relative Perf Gain', fontsize=12)\n",
    "ax.tick_params(axis='both', labelsize=10)\n",
    "\n",
    "# Adding gridlines for better readability (remove vertical lines)\n",
    "ax.grid(axis='y', linestyle='--', linewidth=0.7, alpha=0.7)\n",
    "ax.grid(axis='x', visible=False)\n",
    "\n",
    "plt.gca().spines['top'].set_color('k')\n",
    "plt.gca().spines['right'].set_color('k')\n",
    "plt.gca().spines['left'].set_color('k')\n",
    "plt.gca().spines['bottom'].set_color('k')\n",
    "\n",
    "# Tight layout to avoid clipping\n",
    "plt.tight_layout()\n",
    "\n",
    "# # Optionally save the figure\n",
    "line_figname = f'../figures/scaling.png'\n",
    "plt.savefig(line_figname, format='png', dpi=300, bbox_inches='tight', pad_inches=0.1)\n",
    "\n",
    "# Show the plot\n",
    "plt.show()\n",
    "\n",
    "# display(average_summary_df)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "2b07a76d-23a9-4afc-b943-07f258e33809",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 400x240 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Set default font size for all text elements in your plots\n",
    "plt.rc('font', size=10)          # controls default text sizes\n",
    "plt.rc('axes', titlesize=10)     # font size of the axes title\n",
    "plt.rc('axes', labelsize=10)     # font size of the x and y labels\n",
    "plt.rc('xtick', labelsize=10)    # font size of the x tick labels\n",
    "plt.rc('ytick', labelsize=10)    # font size of the y tick labels\n",
    "plt.rc('legend', fontsize=10)    # legend font size\n",
    "\n",
    "\n",
    "# Rename the selected rows\n",
    "rename_map = {\n",
    "    'open': 'Vanilla',\n",
    "    'positive': 'Positive',\n",
    "    'negative': 'Negative',\n",
    "    'contrast': 'Contrast'\n",
    "}\n",
    "\n",
    "# Define the color palette for different categories\n",
    "colors = {\n",
    "    'open': 'lightgray',\n",
    "    'positive': color_palette[0],\n",
    "    'negative': color_palette[1],\n",
    "    'contrast': color_palette[2],\n",
    "}\n",
    "\n",
    "# Define the preferred order of bars\n",
    "order = ['open', 'positive', 'negative', 'contrast']\n",
    "\n",
    "# Generate color palette for the current order\n",
    "palette = [colors[name] for name in order]\n",
    "\n",
    "all_summary = []\n",
    "\n",
    "# Loop through each task and metric\n",
    "for task, metric in tasks_and_metrics:\n",
    "    patterns = [\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_random_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_positive_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_negative_*.json',\n",
    "        f'../{foldername}/{task}/*/*/*/eval_*_contrast_*.json',\n",
    "    ]\n",
    "    df = load_data(patterns, metric)\n",
    "\n",
    "    # Filtering\n",
    "    df = df[df['noise'] == 0.0]\n",
    "    df = df[df['nsample'].isin([1, 16])]\n",
    "    df = df[df['ah'].isin([8])]\n",
    "\n",
    "    # Add 'name' column based on conditions\n",
    "    df['name'] = df['method']\n",
    "    df.loc[(df['method'] == 'random') & (df['ah'] == 1), 'name'] = 'closed'\n",
    "    df.loc[(df['method'] == 'random') & (df['ah'] == 8), 'name'] = 'open'\n",
    "\n",
    "    # Explode the 'metric' column to ensure scalar values\n",
    "    df = df.explode(metric)\n",
    "    df[metric] = pd.to_numeric(df[metric], errors='coerce')\n",
    "\n",
    "    summary_df = df.groupby('name').agg(mean=(metric, 'mean'), std=(metric, 'std')).reset_index()\n",
    "    summary_df['task'] = task\n",
    "\n",
    "    # Reorder summary_df accordingly\n",
    "    summary_df['name'] = summary_df['name'].replace(rename_map)\n",
    "    summary_df = summary_df.set_index('name').reindex(rename_map.values()).reset_index()\n",
    "\n",
    "    all_summary.append(summary_df)\n",
    "\n",
    "# all summary\n",
    "all_summary_df = pd.concat(all_summary, ignore_index=True)\n",
    "\n",
    "# Calculate average mean and std for each 'name' across all tasks\n",
    "average_summary_df = all_summary_df.groupby('name').agg(mean=('mean', 'mean'), std=('std', 'mean')).reset_index()\n",
    "\n",
    "# Reorder average_summary_df accordingly\n",
    "average_summary_df = average_summary_df.set_index('name').reindex(rename_map.values()).dropna().reset_index()\n",
    "\n",
    "# Create bar plot without error bars\n",
    "fig, ax = plt.subplots(figsize=(4, 2.4))  # Adjust the size as needed\n",
    "barplot = sns.barplot(data=average_summary_df, x='name', y='mean', hue='name', order=average_summary_df['name'], palette=palette, capsize=0.1,\n",
    "                      width=0.6,\n",
    "                      edgecolor='black',\n",
    "                      linewidth=1.2)\n",
    "\n",
    "# Get x positions of the bars\n",
    "x_positions = [p.get_x() + p.get_width() / 2 for p in barplot.patches]\n",
    "\n",
    "# Add error bars manually\n",
    "plt.errorbar(x=x_positions, y=average_summary_df['mean'], yerr=average_summary_df['std'] / len(tasks_and_metrics),\n",
    "             fmt='none', c='black', capsize=5)\n",
    "\n",
    "# Customize plot\n",
    "barplot.set_ylim(average_summary_df['mean'].min() * 0.99, average_summary_df['mean'].max() * 1.01)\n",
    "\n",
    "plt.gca().spines['top'].set_color('k')\n",
    "plt.gca().spines['right'].set_color('k')\n",
    "plt.gca().spines['left'].set_color('k')\n",
    "plt.gca().spines['bottom'].set_color('k')\n",
    "\n",
    "ax.set_xlabel('Method')  # Remove x-label\n",
    "ax.set_ylabel('Success Rate')\n",
    "\n",
    "# Tight layout to avoid clipping\n",
    "plt.tight_layout()\n",
    "\n",
    "# # Optionally save the figure\n",
    "# figname = '../figures/contrast.png'\n",
    "# plt.savefig(figname, format='pdf', dpi=300, bbox_inches='tight', pad_inches=0.1)\n",
    "\n",
    "plt.show()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
